package com.xu.base.utils;

import org.springframework.util.StringUtils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.Date;
import java.util.List;

/**
 * LocalDate工具类
 *
 * @Author: 许乾伟
 * @Date: 2023/1/4 9:20
 */
public class LocalDateUtils {

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public static LocalDate yyyymmddToLocalDate(String dateStr) {
        if (!StringUtils.hasText(dateStr)){
            return null;
        }
        return LocalDate.parse(dateStr, DATE_FORMATTER);
    }
    public static LocalDateTime yyyymmddToLocalDateTime(String dateStr) {
        if (!StringUtils.hasText(dateStr)){
            return null;
        }
        return LocalDate.parse(dateStr, DATE_FORMATTER).atStartOfDay();
    }

    public static LocalDateTime yyyymmddhhmmssToLocalDateTime(String dateStr) {
        if (!StringUtils.hasText(dateStr)){
            return null;
        }
        return LocalDateTime.parse(dateStr, DATE_TIME_FORMATTER);
    }

    public static LocalTime hhmmssToLocalTime(String dateStr) {
        if (!StringUtils.hasText(dateStr)){
            return null;
        }
        return LocalTime.parse(dateStr, TIME_FORMATTER);
    }

    public static String localTimeTohhmmss(LocalTime localTime) {
        if (localTime == null) {
            return "";
        }
        return localTime.format(TIME_FORMATTER);
    }
    /**
     * Date 转 LocalDate
     *
     * @return
     */
    public static LocalDate dateToLocalDate(Date date) {
        if (date==null) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * Date 转 LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        if (date==null) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * 格式化日期
     *
     * @param localDateTime
     * @return
     */
    public static String localDateTimeToyyyymmdd(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return "";
        }
        return localDateTime.format(DATE_FORMATTER);
    }
    /**
     * 格式化日期
     *
     * @param localDate
     * @return
     */
    public static String localDateToyyyymmdd(LocalDate localDate) {
        if (localDate == null) {
            return "";
        }
        return localDate.format(DATE_FORMATTER);
    }

    /**
     * 格式化时间
     *
     * @param localDateTime
     * @return
     */
    public static String localDateTimeTohhmmss(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return "";
        }
        return localDateTime.format(TIME_FORMATTER);
    }

    /**
     * 格式化日期及时间
     *
     * @param localDateTime
     * @return
     */
    public static String localDateTimeToyyyymmddhhmmss(LocalDateTime localDateTime) {
        if (localDateTime==null) {
            return null;
        }
        return localDateTime.format(DATE_TIME_FORMATTER);
    }

    /**
     * 获取两个日期的差  field参数为ChronoUnit.*
     * @param startTime
     * @param endTime
     * @param field  单位(年月日时分秒)
     * @return
     */
    public static long betweenTime(LocalDateTime startTime, LocalDateTime endTime, ChronoUnit field) {
        Period period = Period.between(LocalDate.from(startTime), LocalDate.from(endTime));
        if (field == ChronoUnit.YEARS)
            return period.getYears();
        if (field == ChronoUnit.MONTHS)
            return period.getYears() * 12 + period.getMonths();
        return field.between(startTime, endTime);
    }


    /**
     * 日期加上一个数,根据field不同加不同值,field为ChronoUnit.*
     * @param time
     * @param number
     * @param field
     * @return
     */
    public static LocalDateTime plus(LocalDateTime time, long number, TemporalUnit field) {
        return time.plus(number, field);
    }


    /**
     * 日期减去一个数,根据field不同减不同值,field参数为ChronoUnit.*
     * @param time
     * @param number
     * @param field
     * @return
     */
    public static LocalDateTime minus(LocalDateTime time, long number, TemporalUnit field){
        return time.minus(number,field);
    }

    /**
     * 比较第一个日期是否大于第二个日期
     * @param firstDate 第一个日期
     * @param secondDate 第二个日期
     * @return true-大于;false-不大于
     */
    public boolean localDateIsBefore(LocalDate firstDate, LocalDate secondDate) {
        return firstDate.isBefore(secondDate);
    }

    /**
     * 比较第一个日期是否大于第二个日期
     * @param firstDate 第一个日期
     * @param secondDate 第二个日期
     * @return true-大于;false-不大于
     */
    public boolean localDateTimeIsBefore(LocalDateTime firstDate, LocalDateTime secondDate) {
        return firstDate.isBefore(secondDate);
    }

    /**
     * 计算两个时间（LocalDate 类型） 相差的时间字符串
     * @param firstDate 第一个时间
     * @param secondDate 第二个时间
     * @param fields 条件类型（按传入的类型顺序显示）
     * @return  @return XX天XX小时XX分xx秒
     */
    public static String localDateDiffStr(LocalDate firstDate, LocalDate secondDate, List<ChronoUnit> fields) {
        return localDateTimeDiffStr(firstDate.atStartOfDay(),secondDate.atStartOfDay(),fields);
    }

    /**
     * 计算两个时间（LocalDateTime 类型） 相差的时间字符串
     * @param firstDate 第一个时间
     * @param secondDate 第二个时间
     * @param fields 条件类型（按传入的类型顺序显示）
     * @return  @return XX天XX小时XX分xx秒
     */
    public static String localDateTimeDiffStr(LocalDateTime firstDate, LocalDateTime secondDate, List<ChronoUnit> fields) {
        String str = "";
        if (firstDate == null || secondDate == null) {
            return str;
        }
        for (ChronoUnit field : fields) {
            switch (field) {
                case DAYS:
                    long day = field.between(firstDate, secondDate);
                    str += day == 0 ? "" : day + "天";
                    break;
                case HOURS:
                    long hour = field.between(firstDate, secondDate) % 24;
                    str += (hour == 0 ? "" : hour + "小时");
                    break;
                case MINUTES:
                    long minute = field.between(firstDate, secondDate) % 60;
                    str += (minute == 0 ? "" : minute + "分钟");
                    break;
                case SECONDS:
                    long seconds = field.between(firstDate, secondDate) % 60;
                    str += (seconds == 0 ? "" : seconds + "秒");
                    break;
                default:
                    break;
            }
        }
        return str;
    }
}
